//
//  DiskCaretaker.swift
//  RabbleWabble
//
//  Created by TRS-Mobile on 2021/9/8.
//

import Foundation

final class DiskCaretaker {
    static let decoder = JSONDecoder()
    static let encoder = JSONEncoder()
    
    static func save<T: Codable>(_ obj: T, to fileName: String) throws {
        do {
            let url = createDocumentURL(with: fileName)
            let data = try encoder.encode(obj)
            try data.write(to: url, options: .atomic)
        } catch let error {
            print("Save failed: Object: `\(obj)`, " +
                    "Error: `\(error)`")
            throw error
        }
    }
    
    static func retrieve<T: Codable>(_ type: T.Type, from fileName: String) throws -> T {
        let url = createDocumentURL(with: fileName)
        return try retrieve(T.self, from: url)
    }
    
    static func retrieve<T: Codable>(_ type: T.Type, from url: URL) throws -> T {
        do {
            let data = try Data(contentsOf: url)
            return try decoder.decode(T.self, from: data)
        } catch let error {
            print("Retrieve failed: URL: `\(url)`, Error: `\(error)`")
            throw error
        }
    }
    
    static func createDocumentURL(with fileName: String) -> URL {
        let fileManager = FileManager.default
        let url = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
        return url.appendingPathComponent(fileName)
            .appendingPathExtension("json")
    }
}
